module GYLite
{					
	export class GYTextBase extends egret.TextField implements IGYInteractiveDisplay, IUpdate
	{
		public static _tagReg:RegExp;
		/**设置此属性，初始化MyText时将默认使用嵌入式字体*/
		public static defualtFont:string;
		public static defualtSysFont:string;
		public static defaultFormat;
		public static default_clipXPadding;
		public static default_clipYPadding;
		public static textParser:egret.HtmlTextParser;
		public static init():void
		{
			GYTextBase.defaultFormat = new TextFormat(GYTextBase.defualtSysFont, 12, 0, false, false, false,null,null,"left", null,null,0,5);
			GYTextBase._tagReg = new RegExp("<([^>]*)>","g");
			GYTextBase.default_clipXPadding = 0;
			GYTextBase.default_clipYPadding = 2;
			GYTextBase.textParser = new egret.HtmlTextParser;
		}
		public $textFormat:TextFormat;
		protected _lineWidthArr:Array<number>;
		protected _lineHeightArr:Array<number>;
		public $percentWidth:number;
		public $percentHeight:number;
		public $layoutParent:GYUIComponent;
		protected _layoutMode:LayoutMode;
		public $paddingLeft:number;
		public $paddingRight:number;
		public $paddingTop:number;
		public $paddingBottom:number;
		public $invalidDisplay:boolean;
		public updating:boolean;
		protected _elementsRect:egret.Rectangle;
		protected _toolTip:GYToolTip;
		protected _toolTipOffsetX:number;
		protected _toolTipOffsetY:number;
		protected _toolTipString:string;
		protected _toolTipKeep:boolean;
		protected _followTarget:GYSprite;
		protected _bound:egret.Rectangle;
		protected _elementbound:egret.Rectangle;
		public $disposed:boolean;
		protected _graphics:GYGraphics;
		protected _htmlStr:string;
		protected _textStr:string;
		/**输入模式下，文本y轴偏移*/public inputOffsetY:number;
		/**是否以矩形范围也算入碰撞测试*/public rectHit:boolean;
		/**鼠标是否完全穿透，即不参与碰撞检测*/public mouseThrough:boolean;
		/**防销毁锁定标志，为true则不会被dispose销毁，除非参数forceDispose为true*/public disposeLock:boolean;
		/**是否tip跟随鼠标*/private _toolTipOnKeep:boolean;
		/**是否tip直到鼠标抬起*/public isTipFollow:boolean;
		/**是否使用布局的失效机制*/
		public useInvalidDisplay:boolean;
		/**是否不参与布局计算*/public offLayout:boolean;
		/**阴影颜色*/public _shadowColor:number;
        /**阴影偏移X*/public _shadowOffsetX:number;
        /**阴影偏移Y*/public _shadowOffsetY:number;
        /**阴影大小*/public _shadowBlur:number;

		protected _charStylesMap:any;						
		protected _batchDrawParam:BatchDrawParam;		
		protected _invalidBatch:boolean;

		protected _batch:boolean;
		protected _batchAtlasName:string;
		public constructor()
		{
			super();
			var s = this;
			s.$percentWidth = NaN;
			s.$percentHeight = NaN;
			s.$paddingLeft = 0;
			s.$paddingRight = 0;
			s.$paddingTop = 0;
			s.$paddingBottom = 0;
			s._toolTipOffsetX = 0;
			s._toolTipOffsetY = 0;
			s.inputOffsetY = 0;									
			s.offLayout = false;
			s.$disposed = false;
			s._elementsRect = new egret.Rectangle;
			s._layoutMode = new LayoutMode;
			s._bound = new egret.Rectangle;
			s._elementbound = new egret.Rectangle;		
			s._charStylesMap = egret.createMap();	
			s._shadowBlur = 0;
			s._shadowColor = 0;
			s._shadowOffsetX = 1;
			s._shadowOffsetY = 1;	
			s.initComponent();
		}
		protected initComponent():void
		{var s = this;
			s.useInvalidDisplay = true;
		}
		protected displayChg():void
		{
			LayoutManager.addRenderFunc(this);			
		}
		public $setIsTyping(val:boolean):void
		{			
			super.$setIsTyping(val);
			GYKeyboard.getInstance().isTyping(val);
		}		
		public get mouseX():number
		{
			var s = this;
			s.globalToLocal(GYSprite.stageX, GYSprite.stageY, GYSprite._pt);
			return GYSprite._pt.x;
		}
		public get mouseY():number
		{
			var s = this;
			s.globalToLocal(GYSprite.stageX, GYSprite.stageY, GYSprite._pt);
			return GYSprite._pt.y;
		}
		/**刷新相对布局*/
		public layout():void
		{var s = this;
			if(CommonUtil.GYIs(s.$layoutParent,GYUIComponent))//此处得判断是否GYUIComponent来实施布局
			{
				if(s._layoutMode.top == s._layoutMode.top)
				{
					s.y = s._layoutMode.top;
				}
				else if(s._layoutMode.bottom == s._layoutMode.bottom)
				{
					s.y = s.$layoutParent.height - s.height - s._layoutMode.bottom;
				}			
				else if(s._layoutMode.verticalCenter == s._layoutMode.verticalCenter)
				{
					s.y = (s.$layoutParent.height - s.height>>1)+s._layoutMode.verticalCenter;
				}
				if(s._layoutMode.left == s._layoutMode.left)
				{
					s.x = s._layoutMode.left;
				}
				else if(s._layoutMode.right == s._layoutMode.right)
				{
					s.x = s.$layoutParent.width - s.width - s._layoutMode.right;
				}			
				else if(s._layoutMode.horizonalCenter == s._layoutMode.horizonalCenter)
				{
					s.x = (s.$layoutParent.width - s.width>>1)+s._layoutMode.horizonalCenter;
				}
			}
		}
		/**刷新相对大小*/
		public sizeChange():void
		{var s = this;
			if(s.$layoutParent == null)
				return;
			if(!isNaN(s._layoutMode.left) && !isNaN(s._layoutMode.right))
			{
				s.$setWidth(s.$layoutParent.borderWidth - s._layoutMode.left - s._layoutMode.right);
			}
			else if(!isNaN(s._layoutMode.percentWidth))
			{
				s.$setWidth(s.$layoutParent.borderWidth * s._layoutMode.percentWidth);
			}
			if(!isNaN(s._layoutMode.top) && !isNaN(s._layoutMode.bottom))
			{
				s.$setHeight(s.$layoutParent.borderHeight - s._layoutMode.top - s._layoutMode.bottom);
			}
			else if(!isNaN(s._layoutMode.percentHeight))
			{
				s.$setHeight(s.$layoutParent.borderHeight * s._layoutMode.percentHeight);
			}
		}
		public addLayout(p:GYUIComponent):void
		{var s = this;
			if(s.$layoutParent == p)
				return;
			if(s.$layoutParent)
				s.$layoutParent.removeEventListener(GYViewEvent.VIEWCHANGE,s.layoutChange,s);
			if(s._layoutMode.isPercentSize() || s._layoutMode.layoutMode == LayoutMode.RELATIVE)
			{
				s.$layoutParent = p;
				if(s.$layoutParent)
					s.$layoutParent.addEventListener(GYViewEvent.VIEWCHANGE,s.layoutChange,s);
			}
			else
				s.$layoutParent = null;
		}
		protected layoutChange(e:GYViewEvent):void
		{var s = this;
			s.layout();
			s.sizeChange();
		}
		/**是否百分比布局*/
		public isPercentSize():boolean
		{var s = this;
			return s._layoutMode.isPercentSize();
		}
		public get layoutParent():GYUIComponent
		{var s = this;
			return s.$layoutParent;
		}
		public set left(val:number)
		{var s = this;
			s._layoutMode.left=val;
			s.addLayout(s.getLayoutContainer());
			s.invalidDisplay();
		}
		public set top(val:number)
		{var s = this;
			s._layoutMode.top=val;
			s.addLayout(s.getLayoutContainer());
			s.invalidDisplay();
		}
		public set right(val:number)
		{var s = this;
			s._layoutMode.right=val;
			s.addLayout(s.getLayoutContainer());
			s.invalidDisplay();
		}
		public set bottom(val:number)
		{var s = this;
			s._layoutMode.bottom=val;
			s.addLayout(s.getLayoutContainer());
			s.invalidDisplay();
		}
		public set horizonalCenter(val:number)
		{var s = this;
			s._layoutMode.horizonalCenter=val;
			s.addLayout(s.getLayoutContainer());
			s.invalidDisplay();
		}
		public set verticalCenter(val:number)
		{var s = this;
			s._layoutMode.verticalCenter = val;
			s.addLayout(s.getLayoutContainer());
			s.invalidDisplay();
		}
		
		public get left():number
		{var s = this;
			return s._layoutMode.left;
		}
		public get top():number
		{var s = this;
			return s._layoutMode.top;
		}
		public get right():number
		{var s = this;
			return s._layoutMode.right;
		}
		public get bottom():number
		{var s = this;
			return s._layoutMode.bottom;
		}
		public get horizonalCenter():number
		{var s = this;
			return s._layoutMode.horizonalCenter;
		}
		public get verticalCenter():number
		{var s = this;
			return s._layoutMode.verticalCenter;
		}
		/**获取边界矩形 */
		public getAllBounds(t:IGYDisplay):egret.Rectangle
		{var s = this;
			if(s.scrollRect!=null)
				return s.scrollRect;
			return s.getBounds(s._bound);
		}
		/**获取边界矩形 */
		public getElementsBounds(t:IGYDisplay):egret.Rectangle
		{var s = this;
			if(s.scrollRect!=null)
			{
				s._elementsRect.width = s.scrollRect.width + s.$paddingRight + s.$paddingLeft;
				s._elementsRect.height = s.scrollRect.height + s.$paddingTop + s.$paddingBottom;
				s._elementsRect.x = s.$x;
				s._elementsRect.y = s.$y;
				return s._elementsRect;
			}
			let rect:egret.Rectangle = s.getBounds(s._elementbound);			
			if(s.parent)
			{
				rect.x += s.$x;
				rect.y += s.$y;
			}			
			return rect;
		}
		public set paddingLeft(val:number)
		{var s = this;
			if(s.$paddingLeft == val)
				return;
			s.$setX(s.$x - s.$paddingLeft + val);
			s.$paddingLeft = val;
		}
		public set paddingRight(val:number)
		{var s = this;
			if(s.$paddingRight == val)
				return;
			s.$paddingRight = val;
		}
		public set paddingTop(val:number)
		{var s = this;
			if(s.$paddingTop == val)
				return;
			s.$setY(s.$y - s.$paddingTop + val);			
			s.$paddingTop = val;
		}
		public set paddingBottom(val:number)
		{var s = this;
			if(s.$paddingBottom == val)
				return;
			s.$paddingBottom = val;
		}
		public get paddingLeft():number
		{var s = this;
			return s.$paddingLeft;
		}
		public get paddingRight():number
		{var s = this;
			return s.$paddingRight;
		}
		public get paddingTop():number
		{var s = this;
			return s.$paddingTop;
		}
		public get paddingBottom():number
		{var s = this;
			return s.$paddingBottom;
		}
		
		public set x(val:number)
		{
			super.$setX(val + this.$paddingLeft);			
		}
		public get x():number
		{
			return this.$x;
		}
		public set y(val:number)
		{
			super.$setY(val + this.$paddingTop);			
		}
		public get y():number
		{
			return this.$y;
		}		
		public set width(val:number)
		{							
			this.set_width(val);
		}						
		public set height(val:number)
		{			
			this.set_height(val);
		}				
		public get width():number
		{
			return this.get_width();
		}		
		public get height():number
		{
			return this.get_height();
		}		
		public set_width(val:number):void
		{
			super.$setWidth(val);
			this.invalidDisplay();
		}
		public set_height(val:number):void
		{
			super.$setHeight(val);			
			this.invalidDisplay();
		}
		public get_width():number
		{
			let s = this;
			return super.$getWidth() + s.$paddingLeft + s.$paddingRight;
		}
		public get_height():number
		{
			let s = this;
			return super.$getHeight() + s.$paddingTop + s.$paddingBottom;
		}
		public get baseWidth():number
		{var s = this;
			return super.$getWidth();
		}
		public get baseHeight():number
		{var s = this;
			return super.$getHeight();
		}
		public set percentWidth(val:number)
		{var s = this;
			s._layoutMode.percentWidth=val;
			s.addLayout(s.getLayoutContainer());
			s.sizeChange();
		}
		public set percentHeight(val:number)
		{var s = this;
			s._layoutMode.percentHeight=val;
			s.addLayout(s.getLayoutContainer());
			s.sizeChange();
		}
		
		public set layoutMode(val:LayoutMode)
		{var s = this;
			s._layoutMode = val;
			s.addLayout(s.getLayoutContainer());
			s.sizeChange();
			s.layout();
		}
		/**获取布局容器(因为存在双层容器如GYGroup，用此方法取相对布局容器更准确)*/
		public getLayoutContainer():GYUIComponent
		{var s = this;
			if(s.offLayout)
				return <GYUIComponent>s.parent;
			return <GYUIComponent>(CommonUtil.GYIs(s.parent,InnerSprite)?s.parent.parent:s.parent);
		}
		public get layoutMode():LayoutMode
		{var s = this;
			return s._layoutMode;
		}
		public updateView():void
		{var s = this;
			if(s.$invalidDisplay)
			{
				s.layout();
				s.$invalidDisplay = false;
			}
			if(s.hasEventListener(GYViewEvent.UPDATE_COMPLETE))
				s.dispatchEvent(new GYViewEvent(GYViewEvent.UPDATE_COMPLETE));
		}
		/**刷新显示*/
		public invalidDisplay():void
		{var s = this;
			if(!s.useInvalidDisplay)
				return;
			if(s.$invalidDisplay)
				return;
			s.$invalidDisplay = true;
			s.displayChg();
		}
		public invalidLayout():void
		{
			
		}
		
		/**提示文本,可以通过s.toolTip设置自定义的GYToolTip(继承此类重写实现)*/
		public set toolTipString(val:string)
		{var s = this;
			s._toolTipString = val;
			if(s._toolTip == null)
				s.toolTip = GYSprite.skinTheme.GetToolTip();
			if(s._toolTip.user == this)
				s._toolTip.setText(val);
		}
		public get toolTipString():string
		{var s = this;
			return s._toolTipString;
		}
		public set toolTip(val:GYToolTip)
		{var s = this;
			if(s._toolTip)
				s.removeEventListener(MouseEvent.ROLL_OVER, s.rollOverTip,s);
			s._toolTip = val;
			if(s._toolTip)
				s.addEventListener(MouseEvent.ROLL_OVER, s.rollOverTip,s);
		}
		/**s.toolTip，继承GYToolTip实现自定义@see GYToolTip*/
		public get toolTip():GYToolTip
		{var s = this;
			return s._toolTip;
		}
		protected rollOverTip(e:egret.TouchEvent=null):void
		{var s = this;
			if(s._toolTip.parent == null)
				s.showTip(false);
		}
		public showTip(keep:boolean = false, followTarget:GYSprite = null):void
		{var s = this;
			s._toolTipOnKeep = keep || s._toolTipKeep;
			if(s._toolTipOnKeep)
			{
				GYSprite.addStageDown(s,s.rollOutTip, s);
				s.addEventListener(egret.TouchEvent.TOUCH_END,s.mouseOutTip,s);
				s.removeEventListener(MouseEvent.ROLL_OUT, s.rollOutTip,s);
			}
			else
			{
				s.addEventListener(MouseEvent.ROLL_OUT, s.rollOutTip,s);
			}
			s._toolTip.user = this;
			s._toolTip.tipfollowTarget = s._followTarget?s._followTarget:followTarget;
			if(s._toolTip.parent == null)
			{
				s._toolTip.setText(s._toolTipString);
				s._toolTip.offsetX = s.toolTipOffsetX;
				s._toolTip.offsetY = s.toolTipOffsetY;
				s._toolTip.show(GYSprite.stage, s.isTipFollow);
			}
		}
		protected rollOutTip(e:egret.TouchEvent=null):void
		{var s = this;
			s.removeEventListener(MouseEvent.ROLL_OUT, s.rollOutTip,s);
			if(s._toolTip.parent)
			{
				s._toolTip.hide();
			}
		}
		protected mouseOutTip(e:egret.TouchEvent=null):void
		{var s = this;
			s.removeEventListener(egret.TouchEvent.TOUCH_END,s.mouseOutTip,s);
			s._toolTipOnKeep = false;
			if(s._toolTip.parent)
			{
				s._toolTip.hide();
			}
		}
		/**tip偏移量X*/
		public get toolTipOffsetX():number
		{var s = this;
			return s._toolTipOffsetX;
		}
		
		public set toolTipOffsetX(value:number)
		{var s = this;
			s._toolTipOffsetX = value;
		}
		/**tip偏移量Y*/
		public get toolTipOffsetY():number
		{var s = this;
			return s._toolTipOffsetY;
		}
		
		public set toolTipOffsetY(value:number)
		{var s = this;
			s._toolTipOffsetY = value;
		}
		/**是否保留tip直到鼠标抬起*/
		public get toolTipKeep():boolean
		{var s = this;
			return s._toolTipKeep;
		}
		
		public set toolTipKeep(value:boolean)
		{var s = this;
			s._toolTipKeep = value;
			if(s._toolTip.parent)
			{
				GYSprite.addStageDown(s,s.rollOutTip, s);
				s.addEventListener(egret.TouchEvent.TOUCH_END,s.rollOutTip,s);
				s.removeEventListener(MouseEvent.ROLL_OUT, s.rollOutTip,s);
			}
		}
		/**tip跟随对象*/
		public get followTarget():GYSprite
		{var s = this;
			return s._followTarget;
		}
		
		public set followTarget(value:GYSprite)
		{var s = this;
			s._followTarget = value;
		}
		/**是否刷新中（内部使用请勿修改）*/
		// public get updating():boolean
		// {var s = this;
		// 	return s._updating;
		// }

		// public set updating(value:boolean)
		// {var s = this;
		// 	s._updating = value;
		// }

		public get textWidth():number
		{let s = this;
			if(egret.nativeRender)
			{
				s.$getLinesArr2();
				return s.$TextField[5];
			}
			return egret.superGetter(GYTextBase,this,"textWidth");
		}
		public get textHeight():number
		{let s = this;
			if(egret.nativeRender)
			{
				s.$getLinesArr2();
				return egret.TextFieldUtils.$getTextHeight(s);
			}
			return egret.superGetter(GYTextBase,this,"textHeight");
		}

		/**是否在父级视图范围内(0,0,width,height),可用于做裁切视图时的离屏渲染优化*/
		public inParentView(l:number=0,r:number=0,t:number=0,b:number=0):boolean
		{let s = this;
			let pr:egret.DisplayObjectContainer;
			let sX:number,sY:number,sW:number,sH:number;
			pr = s.parent;
			if(pr)
			{
				if(CommonUtil.GYIs(pr.parent,GYGroup))
				{
					pr = pr.parent;
					sX = (<GYGroup>pr).clipX;
					sY = (<GYGroup>pr).clipY;					
				}
				else
				{
					if(pr.scrollRect)
					{
						sX = pr.scrollRect.x;
						sY = pr.scrollRect.y;
					}
					else
					{
						sX = 0;
						sY = 0;
					}
				}	
				sW = pr.width;
				sH = pr.height;
				if(s.y > sY + sH + b || s.x > sY + sW + r || s.x + s.width < sX + l || s.y + s.height < sY + t)
					return false;	
				return true;
			}
			return false;
		}
		/**销毁
		 * @param disposeChild 是否连同显示列表上的子级也销毁（文本组件没有子级，忽略此参数）
		 * @param removeChild 是否从父级显示列表中移除
		 * @param forceDispose 是否强制销毁，为true表示无视disposeLock标志，进行销毁
		*/
		public dispose(disposeChild:boolean=true, removeChild:boolean = true, forceDispose:boolean=false):void
		{let s= this;			
			if(s.$disposed)return;
			if(s.disposeLock && !forceDispose)return;
			s.$disposed = true;		
			s.text = "";
			if(removeChild && s.parent)
				(<any>s.parent).removeElement(s);			
		}		
		/**是否已经被销毁*/
		public get disposed():boolean
		{
			return this.$disposed;
		}
		///合批操作--------------------------------------------------------------------------------
		protected drawText():number[]
		{
			let s= this;
			var node:egret.sys.TextNode = s.textNode;
			var values = this.$TextField;			
			//GYLite 清理之前的合批文本
			s.clearBatch();			
			//更新文本样式
			node.bold = values[15 /* bold */];
			node.fontFamily = values[8 /* fontFamily */] || egret.TextField.default_fontFamily;
			node.italic = values[16 /* italic */];
			node.size = values[0 /* fontSize */];
			node.stroke = values[27 /* stroke */];
			node.strokeColor = values[25 /* strokeColor */];
			node.textColor = values[2 /* textColor */];
			//先算出需要的数值
			var lines = this.$getLinesArr();
			if (values[5 /* textWidth */] == 0) {
				return [];
			}
			var maxWidth = !isNaN(values[3 /* textFieldWidth */]) ? values[3 /* textFieldWidth */] : values[5 /* textWidth */];
			var textHeight = egret.TextFieldUtils.$getTextHeight(s);
			var drawY = 0;
			var startLine = egret.TextFieldUtils.$getStartLine(s);
			var textFieldHeight = values[4 /* textFieldHeight */];
			if (!isNaN(textFieldHeight) && textFieldHeight > textHeight) {
				var vAlign = egret.TextFieldUtils.$getValign(s);
				drawY += vAlign * (textFieldHeight - textHeight);
			}
			drawY = Math.round(drawY);
			var hAlign = egret.TextFieldUtils.$getHalign(s);
			var drawX = 0;
			var underLineData = [];
			let indent:number;
			indent = s.$textFormat.indent;
			for (var i = startLine, numLinesLength = values[29 /* numLines */]; i < numLinesLength; i++) {
				var line = lines[i];
				var h = line.height;
				drawY += h / 2;
				if (i != startLine) {
					if (values[24 /* type */] == egret.TextFieldType.INPUT && !values[30 /* multiline */]) {
						break;
					}
					if (!isNaN(textFieldHeight) && drawY > textFieldHeight) {
						break;
					}
				}
				drawX = Math.round((maxWidth - line.width) * hAlign) + (i == 0?indent:0);
				for (var j = 0, elementsLength = line.elements.length; j < elementsLength; j++) {
					var element:egret.IWTextElement = line.elements[j];
					var size:number = element.style.size || values[0 /* fontSize */];
					let tx:number,ty:number;
					let str:string = element.text;
					tx = drawX;					
					ty = drawY + (h - size) / 2;
					
					let k:number,len3:number;
					let batchInfo:BatchInfo;
					let tex:TextTexture;
					let batchInfos:BatchInfo[];		
					let color:number,tintColor:number;
					//GYLite 在不存在styleColor的情况下，应使用文本原来的color
					color = element.style.textColor || values[2 /* textColor */];
					tintColor = ColorUtil.revertColor(color);
					if(s.isBatch())
					{						
						batchInfos = [];
						//GYLite 合批
						len3 = str.length;
						for(k=0;k<len3;++k)
						{
							tex = TextTexture.getTextTexture(str.charAt(k),s,element.style);
							batchInfo = AtlasRender.getInstance().addBatch(tex,s);
							if(batchInfo)					
							{
								batchInfo.measureAndDraw();							
								batchInfos.push(batchInfo);
							}											
							s._charStylesMap[tex.hash] = tex;
							
						}												
						node.drawText(tx, ty, str, {batchInfos:batchInfos,color:color,tintColor:tintColor});						
					}	
					else
						node.drawText(tx, ty, str, element.style);
					if (element.style.underline || s.$textFormat.underline) 
					{
						underLineData.push(drawX, drawY + h / 2, element.width, color);
					}				
					drawX += element.width;
				}
				drawY += h / 2 + values[1 /* lineSpacing */];
			}			
			return underLineData;
		}
		public clearBatch():void
		{
			let s = this;
			let tex:TextTexture;
			if(s._charStylesMap)
            {
                for(var key in s._charStylesMap)			
				{
					tex = s._charStylesMap[key];
					if(tex.inPool)											
						continue;					
					tex.$batchManager.removeDisplayBatch(s);
				}					
				s._charStylesMap = egret.createMap();
            }			
		}
		public enableBatch(val:boolean)
		{var s = this;
			s._batch = val;			
		}
		/**是否动态合批，请在文本渲染前设定，默认根据父级容器batch，如果父级也没设定，则默认false*/
		public isBatch():boolean
		{var s = this;
			if(s._batch !== undefined)
				return s._batch;			
			let pr:GYSprite;
			pr = <GYSprite>s.$parent;			
			return pr && pr.isBatch && pr.isBatch();
		}
		public setBatchDrawParam(val:BatchDrawParam):void
		{
			this._batchDrawParam = val;
		}
		/**合批图像的绘制样式**/
		public getBatchDrawParam():BatchDrawParam
		{
			return this._batchDrawParam;
		}
		public setBatchAtlasName(val:string):void
		{
			let s= this;
			s._batchAtlasName = val;			
		}
		/**合批图集名称，不存在找父级容器的，如果都不存在，默认AtlasRender.defaultAtlasName**/
		public getBatchAtlasName():string
		{
			let s = this;
			if(s._batchAtlasName!=null)
				return s._batchAtlasName;
			let pr:GYSprite;
			pr = <GYSprite>s.$parent;	
			return pr && pr.getBatchAtlasName?pr.getBatchAtlasName():AtlasRender.defaultAtlasName;;
		}
		public set underline(val:any)
		{var s = this;
			if(s.$textFormat.underline == val)return;			
			s.$textFormat.underline = val;			
			if(s._htmlStr!=null)
				s.setHTML(s._htmlStr);				
			else
				s.setText(s._textStr);
		}
		public get underline():any
		{var s = this;
			return s.$textFormat.underline;
		}
		public setShadow(shadowBlur:number=0,shadowColor:number=0,shadowOffsetX:number=1,shadowOffsetY:number=1):void
		{
			let s= this;
			s._shadowBlur = shadowBlur;
			s._shadowColor = shadowColor;
			s._shadowOffsetX = shadowOffsetX;
			s._shadowOffsetY = shadowOffsetY;
			s.$invalidateTextField();
		}
		protected setHTML(val:string):void
		{
		}
		protected setText(val:string):void
		{
		}
		public invalidBatch():void
		{
			let s= this;
			if(s._invalidBatch)
				return;
			s._invalidBatch = true;
			s.displayChg();
		}		
		public validBatch():void
		{	
		}
		/**背景填充
		 * @param lines [坐标x,坐标y,宽度w,颜色color]
		*/
		protected fillBackground(lines:number[]=null):void {
			let s = this;
            let graphics:GYGraphics = s._graphics;
            if (graphics) {
                graphics.clear();
            }
            let values = s.$TextField;
            if (values[33 /* background */] || values[31 /* border */] || (lines && lines.length > 0)) {
                if (!graphics) {
                    graphics = new GYGraphics(s);
					graphics.setBatchAtlasName(s.getBatchAtlasName());
                    if (!egret.nativeRender) {
                        var groupNode = new egret.sys.GroupNode();
                        groupNode.addNode(graphics.$renderNode);
                        groupNode.addNode(s.textNode);
                        s.$renderNode = groupNode;
                    }
                    else {
                        s.$renderNode = s.textNode;
                    }
                }
				
                //渲染背景
                if (values[33 /* background */]) {
					graphics.beginFill(values[34 /* backgroundColor */]);
					graphics.drawRect(0, 0, s.$getWidth(), s.$getHeight());
					graphics.endFill();                    
                }
                //渲染边框
                if (values[31 /* border */]) {
					let w:number,h:number;
					w = s.$getWidth();
					h = s.$getHeight();
					graphics.lineStyle(1, values[32 /* borderColor */],1,false,"normal",null);
					graphics.moveTo(0,0);
					graphics.lineTo(w,0);
					graphics.lineTo(w,h);
					graphics.lineTo(0,h);
					graphics.lineTo(0,0);
                }
                //渲染下划线
                if (lines && lines.length > 0) {
                    let textColor:number = values[2 /* textColor */];
                    let lastColor = -1;
                    let length_7 = lines.length;
                    for (let i:number = 0; i < length_7; i += 4) {
                        let x:number = lines[i];
                        let y:number = lines[i + 1];
                        let w:number = lines[i + 2];
                        let color = typeof lines[i + 3] == "number" ? lines[i + 3] : textColor;
                        if (lastColor < 0 || lastColor != color) {
                            lastColor = color;
							graphics.lineStyle(2, color, 1);                            
                        }
						graphics.moveTo(x, y);
						graphics.lineTo(x + w, y);                        
                    }
                }
            }            
        }
		public getLineWidth(ind:number=0):number
		{var s = this;
			return s._lineWidthArr[ind];
		}
		public getLineHeight(ind:number=0):number
		{var s = this;
			return s._lineHeightArr[ind] + s.$textFormat.leading;
		}
		public $updateRenderNode() {
			let s = this;
            if (s.$TextField[24 /* type */] == egret.TextFieldType.INPUT) {
                s.inputUtils._updateProperties();
                if (s.$isTyping) {
                    s.fillBackground();
                    return;
                }
            }
            else if (s.$TextField[3 /* textFieldWidth */] == 0) {
                let graphics:GYGraphics = s._graphics;
                if (graphics) {
                    graphics.clear();
                }
                return;
            }
            let underLines:number[] = s.drawText();
            s.fillBackground(underLines);
            //tudo 宽高很小的情况下webgl模式绘制异常
            var bounds = s.$getRenderBounds();
            var node = s.textNode;
            node.x = bounds.x;
            node.y = bounds.y;
            node.width = Math.ceil(bounds.width);
            node.height = Math.ceil(bounds.height);
            egret.Rectangle.release(bounds);
        }		
		public $getLinesArr2() {
			/**--GYLite--*/
			let s = this;
			var SplitRegex = new RegExp("(?=[\\u00BF-\\u1FFF\\u2C00-\\uD7FF]|\\b|\\s)(?![。，！、》…）)}”】\\.\\,\\!\\?\\]\\:])");
			if(s._lineWidthArr == null)s._lineWidthArr = [];
			if(s._lineHeightArr == null)s._lineHeightArr = [];
			/**
			 * @private
			 * 根据样式测量文本宽度
			 */
			function measureTextWidth(text, values, style) {
				style = style || {};
				var italic = style.italic == null ? values[16 /* italic */] : style.italic;
				var bold = style.bold == null ? values[15 /* bold */] : style.bold;
				var size = style.size == null ? values[0 /* fontSize */] : style.size;
				var fontFamily = style.fontFamily || values[8 /* fontFamily */] || egret.TextField.default_fontFamily;
				return egret.sys.measureText(text, fontFamily, size, bold, italic);
			}
			/**--GYLite--End*/
			var values = s.$TextField;
			if (egret.nativeRender && values[38 /* textLinesChangedForNativeRender */]) {
				egret_native.updateNativeRender();
				values[38 /* textLinesChangedForNativeRender */] = false;
				return;
			}
			if (!values[18 /* textLinesChanged */]) {
				return s.linesArr;
			}
			values[18 /* textLinesChanged */] = false;
			var text2Arr = s.textArr;
			s.linesArr.length = 0;
			values[6 /* textHeight */] = 0;
			values[5 /* textWidth */] = 0;
			var textFieldWidth = values[3 /* textFieldWidth */];
			//宽度被设置为0
			if (textFieldWidth != textFieldWidth && textFieldWidth == 0) {
				values[29 /* numLines */] = 0;
				return [{ width: 0, height: 0, charNum: 0, elements: [], hasNextLine: false }];
			}
			var linesArr = this.linesArr;
			var lineW = 0;
			var lineCharNum = 0;
			var lineH = 0;
			var lineCount = 0;
			var lineElement;
			for (var i = 0, text2ArrLength = text2Arr.length; i < text2ArrLength; i++) {
				var element = text2Arr[i];
				//可能设置为没有文本，忽略绘制
				if (!element.text) {
					if (lineElement) {
						lineElement.width = lineW;
						lineElement.height = lineH;
						lineElement.charNum = lineCharNum;
						values[5 /* textWidth */] = Math.max(values[5 /* textWidth */], lineW);
						values[6 /* textHeight */] += lineH;
					}
					continue;
				}
				element.style = (<any>element.style || {});
				var text = element.text.toString();
				var textArr = text.split(/(?:\r\n|\r|\n)/);
				let indent:number;
				indent = s.$textFormat.indent;
				for (var j = 0, textArrLength = textArr.length; j < textArrLength; j++) {
					if (linesArr[lineCount] == null) {
						lineElement = { width: 0, height: 0, elements: [], charNum: 0, hasNextLine: false };
						linesArr[lineCount] = lineElement;
						lineW = lineCount ==0?indent:0;
						lineH = 0;
						lineCharNum = 0;						
					}
					if (values[24 /* type */] == egret.TextFieldType.INPUT) {
						lineH = values[0 /* fontSize */];
					}
					else {
						lineH = Math.max(lineH, element.style.size || values[0 /* fontSize */]);
					}
					var isNextLine = true;
					if (textArr[j] == "") {
						if (j == textArrLength - 1) {
							isNextLine = false;
						}
					}
					else {
						var w = measureTextWidth(textArr[j], values, element.style);
						if (isNaN(textFieldWidth) || this["_autoWidth"]) {//GYLite 羔羊引擎的自动宽度也通过此处
							lineW += w;
							lineCharNum += textArr[j].length;
							lineElement.elements.push({
								width: w,
								text: textArr[j],
								style: element.style
							});
							if (j == textArrLength - 1) {
								isNextLine = false;
							}
						}
						else {
							if (lineW + w <= textFieldWidth) {
								lineElement.elements.push({
									width: w,
									text: textArr[j],
									style: element.style
								});
								lineW += w;
								lineCharNum += textArr[j].length;
								if (j == textArrLength - 1) {
									isNextLine = false;
								}
							}
							else {
								var k = 0;
								var ww = 0;
								var word = textArr[j];
								var words = void 0;
								if (values[19 /* wordWrap */]) {
									words = word.split(SplitRegex);
								}
								else {
									words = word.match(/./g);
								}
								var wl = words.length;
								var charNum = 0;
								for (; k < wl; k++) {
									// detect 4 bytes unicode, refer https://mths.be/punycode
									var codeLen = words[k].length;
									var has4BytesUnicode = false;
									if (codeLen == 1 && k < wl - 1) {
										var charCodeHigh = words[k].charCodeAt(0);
										var charCodeLow = words[k + 1].charCodeAt(0);
										if (charCodeHigh >= 0xD800 && charCodeHigh <= 0xDBFF && (charCodeLow & 0xFC00) == 0xDC00) {
											var realWord = words[k] + words[k + 1];
											codeLen = 2;
											has4BytesUnicode = true;
											w = measureTextWidth(realWord, values, element.style);
										}
										else {
											w = measureTextWidth(words[k], values, element.style);
										}
									}
									else {
										w = measureTextWidth(words[k], values, element.style);
									}
									// w = measureTextWidth(words[k], values, element.style);										
									if (lineW != 0 && lineW + w > textFieldWidth && lineW + k != 0) {
										break;
									}
									if (ww + w > textFieldWidth) {
										var words2 = words[k].match(/./g);
										for (var k2 = 0, wl2 = words2.length; k2 < wl2; k2++) {
											// detect 4 bytes unicode, refer https://mths.be/punycode
											var codeLen = words2[k2].length;
											var has4BytesUnicode2 = false;
											if (codeLen == 1 && k2 < wl2 - 1) {
												var charCodeHigh = words2[k2].charCodeAt(0);
												var charCodeLow = words2[k2 + 1].charCodeAt(0);
												if (charCodeHigh >= 0xD800 && charCodeHigh <= 0xDBFF && (charCodeLow & 0xFC00) == 0xDC00) {
													var realWord = words2[k2] + words2[k2 + 1];
													codeLen = 2;
													has4BytesUnicode2 = true;
													w = measureTextWidth(realWord, values, element.style);
												}
												else {
													w = measureTextWidth(words2[k2], values, element.style);
												}
											}
											else {
												w = measureTextWidth(words2[k2], values, element.style);
											}
											//w = measureTextWidth(words2[k2], values, element.style);
											if (k2 > 0 && lineW + w > textFieldWidth) {
												break;
											}
											// charNum += words2[k2].length;
											charNum += codeLen;
											ww += w;
											lineW += w;
											lineCharNum += charNum;
											if (has4BytesUnicode2) {
												k2++;
											}
										}
									}
									else {
										 // charNum += words[k].length;
										charNum += codeLen;
										ww += w;
										lineW += w;
										lineCharNum += charNum;
									}
									if (has4BytesUnicode) {
										k++;
									}
								}
								if (k > 0) {
									lineElement.elements.push({
										width: ww,
										text: word.substring(0, charNum),
										style: element.style
									});
									var leftWord = word.substring(charNum);
									var m = void 0;
									var lwleng = leftWord.length;
									for (m = 0; m < lwleng; m++) {
										if (leftWord.charAt(m) != " ") {
											break;
										}
									}
									textArr[j] = leftWord.substring(m);
								}
								if (textArr[j] != "") {
									j--;
									isNextLine = false;
								}
							}
						}
					}
					if (isNextLine) {
						lineCharNum++;
						lineElement.hasNextLine = true;
					}
					s._lineWidthArr[lineCount] = lineW;//GYLite 记录宽度
					s._lineHeightArr[lineCount] = lineH;//GYLite 记录高度
					if (j < textArr.length - 1) {
						lineElement.width = lineW;
						lineElement.height = lineH;
						lineElement.charNum = lineCharNum;
						values[5 /* textWidth */] = Math.max(values[5 /* textWidth */], lineW);
						values[6 /* textHeight */] += lineH;							
						//if (this._type == TextFieldType.INPUT && !this._multiline) {
						//    this._numLines = linesArr.length;
						//    return linesArr;
						//}
						lineCount++;
					}
				}
				if (i == text2Arr.length - 1 && lineElement) {
					lineElement.width = lineW;
					lineElement.height = lineH;
					lineElement.charNum = lineCharNum;
					values[5 /* textWidth */] = Math.max(values[5 /* textWidth */], lineW);
					values[6 /* textHeight */] += lineH;						
				}
			}
			values[29 /* numLines */] = linesArr.length;
			s._lineWidthArr.length = values[29 /* numLines */];//GYLite 记录行数
			s._lineHeightArr.length = values[29 /* numLines */];//GYLite 记录行数				
			return linesArr;
		}
	}
}